package main

import "fmt"

/*
https://peakchen.blog.csdn.net/article/details/130921516

适配器模式原理详细解释：
适配器模式（Adapter Pattern）是一种结构型设计模式，用于将一个类的接口转换成客户端所期望的另一个接口。
适配器模式使得原本由于接口不兼容而不能一起工作的类能够协同工作。

适配器模式通过引入适配器来解决接口不兼容的问题。适配器实现了客户端所期望的目标接口，并封装了原始类的接口，从而使得客户端可以通过适配器与原始类进行交互。
底层结构图：
以下是适配器模式的经典结构图：
+-----------------------+
|        Client         |
+-----------------------+
| + Request()            |
+-----------------------+
        ^
        |     +-----------------------+
        |     |       Target(目标接口)  |
        +---->|-----------------------|
              | + Request()            |
              +-----------------------+
                          ^
                          |
                          v
              +-----------------------+
              |       Adapter(适配器)   |
              |-----------------------|
              | - adaptee: Adaptee    |
              +-----------------------+
              | + Request()            |
              +-----------------------+
                          ^
                          |
                          v
              +-----------------------+
              |       Adaptee(原始类)   |
              +-----------------------+
              | + SpecificRequest()    |
              +-----------------------+

在上述结构图中，Client 是客户端，它通过调用 Request() 方法来使用目标接口。
	Target 是目标接口，定义了客户端所期望的方法。
	Adapter 是适配器，它实现了目标接口，并持有一个对原始类的引用（adaptee），通过调用原始类的方法来实现目标接口的方法。、
	Adaptee 是原始类，它拥有一组不兼容于目标接口的方法。

使用场景解释：
适配器模式适用于以下场景：
    1.当需要使用一个已存在的类，并且其接口与需求不兼容时，可以使用适配器模式。
		例如，使用第三方库提供的接口，但是该接口与当前系统的接口不匹配。
    2.当需要创建一个可复用的类，该类与其他类具有不兼容的接口时，可以使用适配器模式。
		适配器可以将这些不兼容的接口转换为统一的目标接口，使得这个类可以与其他类协同工作。

当前都有哪些产品在使用：
适配器模式是一种常用的设计模式，广泛应用于软件开发和系统集成中。以下是一些常见的产品和框架，可能使用了适配器模式：
    1.数据库驱动程序：数据库驱动程序通常通过适配器模式提供了统一的接口，使得不同的数据库可以使用相同的代码进行访问和操作。
    2.消息队列中间件：消息队列中间件（如Apache Kafka、RabbitMQ）通常提供了适配器，用于将不同的消息协议转换为统一的接口。
    3.GUI工具包：GUI工具包（例如Swing、JavaFX、Qt）通常提供了适配器，用于将底层操作系统提供的低级接口转换为更高级的接口，以便开发人员更方便地使用。
    4.第三方API库：许多第三方API库提供了适配器，使得开发人员可以使用统一的接口与不同的服务进行交互，例如各种云服务的SDK。
*/

// Target 目标接口
type Target interface {
	Request() //请求方法
}

// Adapter 适配器
type Adapter struct {
	adaptee *Adaptee //将原始类作为属性注入进来
}

// Request 适配器实现目标接口的方法
func (a *Adapter) Request() {
	a.adaptee.SpecificRequest() //调用的是适配器的Request方法, 提供服务的是原始类的请求方法
}

// Adaptee 原始类
type Adaptee struct{}

// SpecificRequest 原始类的方法
func (a *Adaptee) SpecificRequest() {
	fmt.Println("原始类的具体请求方法")
}

func main() {
	adaptee := &Adaptee{}
	adapter := &Adapter{adaptee}

	adapter.Request()
}
